/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package servidor.archivos;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Serializable;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Clase que gestiona las operaciones en el Servidor de Archivos
 * @author Eduardo
 */
public class OArchivos extends UnicastRemoteObject implements IArchivos, Serializable {

    private String servidorArchivos = "C:/Users/Eduardo/Documents/SistemasDistribuidos/Practica/"
            + "TallerRMI/src/servidor/archivos/Archivos/";
    private File directorioServidorArchivos = new File(servidorArchivos);

    public OArchivos() throws RemoteException  {
        super();
    }

    /**
     * Método que se encarga de actualizar el archivo de bitácora
     * @param ipCliente Ip del cliente que realiza la transacción
     * @param operacion Operación que intenta realiza el cliente
     * @param resultadoOperacion Resultado de la operación intentada por el cliente
     * @param comentarioOperacion Comentario de la operación realizada por el cliente
     */
    public void escribirEnBitacora(String ipCliente, String operacion, String resultadoOperacion,
            String comentarioOperacion) {
        try {
            DateFormat formatoFecha = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
            Date fechaActual = new Date();

            /**
             * El parámetro "true" indica que debe hacerse append al archivo
             */
            FileWriter bitacora = new FileWriter(servidorArchivos + "Bitacora.txt", true);
            PrintWriter writer = new PrintWriter(bitacora);

            writer.println(ipCliente + " - " + operacion + " - " + formatoFecha.format(fechaActual)
                    + " - " + resultadoOperacion + " - " + comentarioOperacion);
               
            bitacora.close();
            writer.close();
        } catch (IOException ex) {
            System.out.println("No se encontró el archivo de bitácora en el Servidor de Archivos");
        }
    }

    /**
     * Método que permite comprobar si el archivo enviado por el usuario existe en el Servidor de
     * Archivos
     * @param nombreArchivo Nombre del archivo que se busca
     * @return Devuelve un valor lógico para confirmar o no la existencia del archivo
     */
    private boolean existeArchivo(String nombreArchivo) {
        boolean existeArchivo = false;

        /**
         * Agrupando todos los ficheros del directorio en un arreglo
         */
        String[] ficheros = this.directorioServidorArchivos.list();

        /**
         * Recorriendo todos los archivos del directorio para comprobar si el archivo
         * seleccionado por el usuario se encontraba o no alojado en el directorio
         */
        for (int i = 0; i < ficheros.length; i++)
            if (ficheros[i].equalsIgnoreCase(nombreArchivo)) {
                existeArchivo = true;
                break;
            }

        return existeArchivo;
    }

    /**
     * Método que permite mostrar el contenido del archivo que indica el usuario
     * @param nombreArchivo Nombre del archivo que el usuario pretende visualizar
     * @return Devuelve el contenido del archivo o un mensaje de error
     */
    public String vista(String nombreArchivo, String ipCliente) {
        try {
            if (!existeArchivo(nombreArchivo) || (nombreArchivo.equals("Bitacora.txt"))) {
                escribirEnBitacora(ipCliente, "Vista", "Error", "No existe el archivo " +
                        nombreArchivo);

                return "El archivo " + nombreArchivo + " no se encuentra alojado\nen el Servidor "
                        + "de Archivos";
            }

            /**
             * Definiendo una estructura para almacenar la información del fichero seleccionado por
             * el usuario
             */
            StringBuilder contenidoArchivo = new StringBuilder();

            /**
             * Habilitando un buffer de lectura para acceder al fichero seleccionado por el usuario
             */
            BufferedReader reader = new BufferedReader(new FileReader
                    (new File(servidorArchivos + nombreArchivo)));
            
            /**
             * Recorriendo cada línea del archivo seleccionado por el usuario y almacenando su
             * contenido en la estructura definida previamente
             */
            String linea = reader.readLine();
            while (linea != null) {
                contenidoArchivo.append(linea);
                contenidoArchivo.append(System.getProperty("line.separator"));
                linea = reader.readLine();
            }
            
            /**
             * Deshabilitando el buffer de lectura
             */
            reader.close();

            escribirEnBitacora(ipCliente, "Vista", "Exito", "Archivo " + nombreArchivo +
                    " visualizado exitosamente");

            return contenidoArchivo.toString();
        } catch (IOException ex) {
            return "El archivo no fue encontrado en el Servidor de Archivos";
        }
    }

    /**
     * Método que permite actualizar un archivo alojado en el servidor de archivos o crearlo si no
     * existe
     * @param fichero Fichero que pretende actualizarse en el Servidor de Archivos
     * @return Devuelve la información con la información de la transacción
     */
    public String actualizacion(File fichero, String ipCliente) {
        if (fichero.getName().equalsIgnoreCase("Bitacora.txt")) {
            escribirEnBitacora(ipCliente, "Actualizacion", "Error", "El archivo de bitácora no "
                    + "puede ser modificado");

            return "El archivo de bitácora no puede ser modificado";
        }

        boolean existeArchivo = existeArchivo(fichero.getName());

        try {
            /**
             * Declarando el fichero seleccionado por el usuario y el que debería estar en el
             * Servidor de Archivos
             */
            File ficheroSeleccionado = fichero;
            File ficheroAlojado = new File(servidorArchivos + fichero.getName());

            /**
             * Definiendo una estructura para almacenar la información del fichero seleccionado por
             * el usuario
             */
            StringBuilder contenidoFicheroSeleccionado = new StringBuilder();

            /**
             * Habilitando un buffer de lectura para acceder al fichero seleccionado por el usuario
             */
            BufferedReader reader = new BufferedReader(new FileReader(ficheroSeleccionado));


            /**
             * Recorriendo cada línea del archivo seleccionado por el usuario y almacenando su
             * contenido en la estructura definida previamente
             */
            String linea = reader.readLine();
            while (linea != null) {
                contenidoFicheroSeleccionado.append(linea);
                contenidoFicheroSeleccionado.append(System.getProperty("line.separator"));

                linea = reader.readLine();
            }

            /**
             * Deshabilitando el buffer de lectura
             */
            reader.close();

            /**
             * Habilitando un buffer de escritura para almacenar los datos del archivo seleccionado
             * por el usuario en el Servidor de Archivos, o bien en el archivo existente o bien
             * creando un nuevo archivo
             */
            PrintWriter writer = new PrintWriter(new FileWriter(ficheroAlojado));

            /**
             * Escribiendo el contenido en el Servidor de Archivo
             */
            writer.print(contenidoFicheroSeleccionado);

            /**
             * Deshabilitando el buffer de escritura
             */
            writer.close();

            if (existeArchivo) {
                escribirEnBitacora(ipCliente, "Actualizacion", "Exito", "Archivo " +
                        fichero.getName() + " actualizado exitosamente");

                return "El archivo " + fichero.getName() + " se encontraba alojado\nen el Servidor "
                        + "de Archivos y su contenido\nfue actualizado exitosamente";

            }

            escribirEnBitacora(ipCliente, "Actualizacion", "Exito", "Archivo " +
                        fichero.getName() + " creado exitosamente");

            return "El archivo " + fichero.getName() + " no se encontraba alojado\nen el Servidor "
                    + "de Archivos, pero fue agregado exitosamente";
        } catch (IOException ex) {
            return "El archivo no fue encontrado en el Servidor de Archivos";
        }
    }

    /**
     * Método que permite eliminar un archivo del servidor de archivos
     * @param nombreArchivo Nombre del archivo que se pretende eliminar
     * @return Devuelve un mensaje de operación exitosa o de error
     */
    public String eliminarArchivo(String nombreArchivo, String ipCliente) {
        if (!existeArchivo(nombreArchivo) || (nombreArchivo.equals("Bitacora.txt"))) {
            escribirEnBitacora(ipCliente, "Eliminacion", "Error", "El archivo de bitácora no "
                    + "puede ser eliminado");

            return "El archivo " + nombreArchivo + " no se encuentra alojado\nen el Servidor de "
                    + "Archivos";
        }

        File archivoAeliminar = new File(servidorArchivos + nombreArchivo);
        
        if (!archivoAeliminar.delete()) {
            escribirEnBitacora(ipCliente, "Eliminacion", "Error", "Archivo " + nombreArchivo
                    + " no pudo ser eliminado");

            return "No fue posible eliminar el archivo " + nombreArchivo + "\ndel Servidor de "
                    + "Archivos";
        }

        escribirEnBitacora(ipCliente, "Eliminacion", "Exito", "Archivo " + nombreArchivo
                    + " eliminado exitosamente");

        return "El archivo " + nombreArchivo + " fue eliminado\nexitosamente del Servidor de "
                + "Archivos";
    }

    /**
     * Método que permite visualizar el contenido de la bitácora
     * @return Devuelve el contenido de la bitácora
     */
    public String consultarBitacora() {
        try {
            if (!existeArchivo("Bitacora.txt"))
                return "Aún no se ha registrado alguna transacción en la bitácora del Servidor de "
                        + "Archivos";

            /**
             * Definiendo una estructura para almacenar la información del archivo de bitácora
             */
            StringBuilder contenidoBitacora = new StringBuilder();

            /**
             * Habilitando un buffer de lectura para acceder a la bitácora
             */
            File ficheroBitacora = new File(servidorArchivos + "Bitacora.txt");
            BufferedReader reader = new BufferedReader(new FileReader(ficheroBitacora));

            /**
             * Recorriendo cada línea del archivo de bitácora y almacenando su contenido en la
             * estructura definida previamente
             */
            String linea = reader.readLine();
            while (linea != null) {
                contenidoBitacora.append(linea);
                contenidoBitacora.append(System.getProperty("line.separator"));
                linea = reader.readLine();
            }

            return contenidoBitacora.toString();
        } catch (IOException ex) {
            return "El archivo no fue encontrado en el Servidor de Archivos";
        }
    }
}